/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.gitee.huangjianbo.supos.openapi.core.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.gitee.huangjianbo.supos.openapi.core.constants.ApiClientConstant;
import io.gitee.huangjianbo.supos.openapi.core.errors.InvalidEndpointException;
import io.gitee.huangjianbo.supos.openapi.core.headers.CommonHeaders;
import io.gitee.huangjianbo.supos.openapi.core.http.HttpLanguage;
import io.gitee.huangjianbo.supos.openapi.core.tools.InetUtils;
import io.gitee.huangjianbo.supos.openapi.core.tools.StringUtils;

import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Locale;

/**
 * 客户端配置
 *
 * @author tomcat
 * @version 1.0
 */
public class SuposApiClientConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(SuposApiClientConfig.class);

    private static final String ENV_SUPOS_ADDRESS = "SUPOS_ADDRESS";
    private static final String ENV_SUPOS_APP_ID = "SUPOS_APP_ID";
    private static final String ENV_SUPOS_SERVICE_NAME = "SUPOS_APP_SERVICE_NAME";
    private static final String ENV_SUPOS_TENANT_ID = "SUPOS_APP_TENANT_ID";
    private static final String ENV_SUPOS_HOSTNAME = "HOSTNAME";
    private static final String ENV_SUPOS_LANGUAGE = "OSLANG";
    private static final String ENV_SUPOS_ACCESS_KEY = "SUPOS_APP_ACCOUNT_ID";
    private static final String ENV_SUPOS_SECRET_KEY = "SUPOS_APP_SECRET_KEY";

    /**
     * supOS的访问令牌
     * <p>
     * 用户登录或单点登录生成的
     */
    private String ticket;
    /**
     * 访问AK
     */
    private String accessKey;
    /**
     * 访问SK
     */
    private String secretKey;
    /**
     * supOS的访问地址
     */
    private SuposEndpoint endpoint = SuposEndpoint.of();
    /**
     * APP的唯一ID
     */
    private String appId;
    /**
     * 租户ID
     */
    private String tenantId;
    /**
     * 默认语言，当调用方未指定时使用此值为参
     */
    private HttpLanguage defaultLanguage;
    /**
     * 服务名称
     */
    private String serviceName;
    /**
     * 服务IP
     */
    private final String serviceIp;

    private SuposApiClientConfig() {
        String suposAddress = System.getProperty(ENV_SUPOS_ADDRESS);
        if (StringUtils.isNotEmpty(suposAddress)) {
            endpoint(suposAddress);
        }
        appId(System.getProperty(ENV_SUPOS_APP_ID));
        accessKey(System.getProperty(ENV_SUPOS_ACCESS_KEY));
        secretKey(System.getProperty(ENV_SUPOS_SECRET_KEY));
        tenantId(System.getProperty(ENV_SUPOS_TENANT_ID, ApiClientConstant.DEFAULT_TENANT));
        defaultLanguage(HttpLanguage.valueOf(System.getProperty(ENV_SUPOS_LANGUAGE, HttpLanguage.zh_CN.name())));
        serviceName(System.getProperty(ENV_SUPOS_SERVICE_NAME));
        if (StringUtils.isEmpty(this.serviceName)) {
            serviceName(System.getProperty(ENV_SUPOS_HOSTNAME));
        }
        if (StringUtils.isEmpty(this.serviceName)) {
            serviceName(determineHostIp());
        }
        this.serviceIp = determineHostIp();

        LOGGER.info("===========================================================================");
        LOGGER.info("=                  Welcome to java openapi SDK                            =");
        LOGGER.info("=                         {}                                         =", CommonHeaders.getBuildVersion());
        LOGGER.info("===========================================================================");
    }

    private String determineHostIp() {
        InetAddress inetAddress = InetUtils.getLocalHostLANAddress();
        return inetAddress.getHostAddress();
    }

    public static SuposApiClientConfig of() {
        return new SuposApiClientConfig();
    }

    public SuposApiClientConfig ticket(String ticket) {
        this.ticket = ticket;
        return this;
    }

    public SuposApiClientConfig accessKey(String accessKey) {
        this.accessKey = accessKey;
        return this;
    }

    public SuposApiClientConfig secretKey(String secretKey) {
        this.secretKey = secretKey;
        return this;
    }

    public SuposApiClientConfig appId(String appId) {
        this.appId = appId;
        return this;
    }

    public SuposApiClientConfig tenantId(String tenantId) {
        this.tenantId = tenantId;
        return this;
    }

    public SuposApiClientConfig endpoint(SuposEndpoint endpoint) {
        this.endpoint = endpoint;
        return this;
    }

    public SuposApiClientConfig endpoint(String endpoint) {
        try {
            URI uri = new URI(endpoint);
            return endpoint(SuposEndpoint.of(uri));
        } catch (URISyntaxException e) {
            throw new InvalidEndpointException(e.getMessage(), e);
        }
    }

    public SuposApiClientConfig defaultLanguage(HttpLanguage defaultLanguage) {
        this.defaultLanguage = defaultLanguage;
        return this;
    }

    public SuposApiClientConfig defaultLanguage(Locale locale) {
        this.defaultLanguage = HttpLanguage.valueOf(locale.toString());
        return this;
    }

    public SuposApiClientConfig defaultLanguage(String language, String country) {
        return defaultLanguage(new Locale(language.toLowerCase(), country.toUpperCase()));
    }

    public SuposApiClientConfig serviceName(String serviceName) {
        this.serviceName = serviceName;
        return this;
    }

    public String getTenantId() {
        return tenantId;
    }

    public String getAppId() {
        return appId;
    }

    public SuposEndpoint getEndpoint() {
        return endpoint;
    }

    public String getSecretKey() {
        return secretKey;
    }

    public String getAccessKey() {
        return accessKey;
    }

    public HttpLanguage getDefaultLanguage() {
        return defaultLanguage;
    }

    public String getTicket() {
        return ticket;
    }

    public String getServiceName() {
        return serviceName;
    }

    public String getServiceIp() {
        return serviceIp;
    }

    @Override
    public String toString() {
        return "SuposApiClientConfig{" +
                "ticket='" + ticket + '\'' +
                "', accessKey='" + accessKey + '\'' +
                "', secretKey='" + secretKey + '\'' +
                "', defaultLanguage='" + defaultLanguage.name() + '\'' +
                "', tenantId='" + tenantId + '\'' +
                "', appId='" + appId + '\'' +
                "', endpoint='" + endpoint.toString() + '\'' +
                "', serviceName='" + serviceName + '\'' +
                "', serviceIp='" + serviceIp + '\'' +
                "'}';";
    }
}
